package com.sxj.PDMS.controller.student;

import com.sxj.PDMS.common.BaseResponse;
import com.sxj.PDMS.common.ErrorCode;
import com.sxj.PDMS.common.Result;
import com.sxj.PDMS.constant.JwtClaimsConstant;
import com.sxj.PDMS.exception.BusinessException;
import com.sxj.PDMS.exception.ThrowUtils;
import com.sxj.PDMS.model.dto.student.StudentLoginRequest;
import com.sxj.PDMS.model.dto.student.StudentRegisterRequest;
import com.sxj.PDMS.model.dto.student.StudentUpdatePasswordRequest;
import com.sxj.PDMS.model.dto.student.StudentUpdateRequest;
import com.sxj.PDMS.model.entity.Student;
import com.sxj.PDMS.model.vo.StudentLoginVO;
import com.sxj.PDMS.model.vo.StudentTimesVO;
import com.sxj.PDMS.properties.JwtProperties;
import com.sxj.PDMS.service.StudentService;
import com.sxj.PDMS.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@CrossOrigin
@RestController
@RequestMapping("/student")
@Slf4j
public class StudentController {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StudentService studentService;
    @Autowired
    private JwtProperties jwtProperties;
    public static final String SALT = "tyutrjxy";

    /**
     * 用户注册
     *
     * @param studentRegisterRequest
     * @return
     */
    @PostMapping("/register")
    public BaseResponse<String> studentRegister(@RequestBody StudentRegisterRequest studentRegisterRequest) {
        log.info("用户注册：{}", studentRegisterRequest);

        if (studentRegisterRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String result = studentService.studentRegister(studentRegisterRequest);
        return Result.success(result);
    }

    /**
     * 用户登录
     *
     * @param studentLoginRequest
     * @param request
     * @return
     */
    @PostMapping("/login")
    public BaseResponse<StudentLoginVO> studentLogin(@RequestBody StudentLoginRequest studentLoginRequest, HttpServletRequest request) {

        log.info("学生登录：{}", studentLoginRequest);

        String studentNumber = studentLoginRequest.getStudentNumber();
        String password = studentLoginRequest.getPassword();

        StudentLoginVO studentLoginVO = studentService.login(studentNumber, password, request);

        //登录成功后，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.STUDENT_NUMBER, studentNumber);
        String token = JwtUtil.createJWT(
                jwtProperties.getStudentSecretKey(),
                jwtProperties.getStudentTtl(),
                claims);

        studentLoginVO.setAuthentication(token);

        return Result.success(studentLoginVO);
    }

    /**
     * 用户更新密码
     *
     * @param studentUpdatePasswordRequest
     * @return
     */

    @PutMapping("/modify_password")
    public BaseResponse<Boolean> updateStudentPassword(@RequestBody StudentUpdatePasswordRequest studentUpdatePasswordRequest) {
        if (studentUpdatePasswordRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 1. 校验
        if (StringUtils.isAnyBlank(studentUpdatePasswordRequest.getStudentNumber(),
                studentUpdatePasswordRequest.getPassword(),
                studentUpdatePasswordRequest.getNewPassword(),
                studentUpdatePasswordRequest.getConfirmPassword()))
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");

        if (studentUpdatePasswordRequest.getPassword().length() < 6)
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "旧密码长度不能小于6");

        if (studentUpdatePasswordRequest.getNewPassword().length() < 6 || studentUpdatePasswordRequest.getConfirmPassword().length() < 6)
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "新密码长度不能小于6");
        // 密码和校验密码相同
        if (!studentUpdatePasswordRequest.getNewPassword().equals(studentUpdatePasswordRequest.getConfirmPassword())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
        }
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + studentUpdatePasswordRequest.getNewPassword()).getBytes());
        Student student = studentService.getById(studentUpdatePasswordRequest.getStudentNumber());
        student.setPassword(encryptPassword);
        System.out.println(student);
        boolean result = studentService.updateById(student);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        //更新数据后进行缓存更新

        redisTemplate.opsForValue().set("student:student_" + studentUpdatePasswordRequest.getStudentNumber(), 7, TimeUnit.DAYS);
        return Result.success(true);
    }

    /**
     * 用户更新信息
     *
     * @param studentUpdateRequest
     * @param request
     * @return
     */
    @PutMapping("/modify_info")
    public BaseResponse<Boolean> updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest,
                                               HttpServletRequest request) {
        if (studentUpdateRequest == null || studentUpdateRequest.getStudentNumber() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Student student = studentService.getById(studentUpdateRequest.getStudentNumber());
        BeanUtils.copyProperties(studentUpdateRequest, student);
        boolean result = studentService.updateById(student);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        //更新数据后进行缓存更新
        //todo: 走Redis
        redisTemplate.opsForValue().set("student:student_" + studentUpdateRequest.getStudentNumber(), student, 7, TimeUnit.DAYS);
        return Result.success(true);
    }


    /**
     * 获取当前登录学生
     *
     * @return
     */
    @GetMapping("/get_login_student")
    public BaseResponse<StudentLoginVO> getLoginStudent() {
        log.info("获取当前登录学生");
        StudentLoginVO student = studentService.getLoginStudent();
        if (student == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }

        return Result.success(student);

    }

    /**
     * 获取学生信息
     *
     * @param studentNumber
     * @return
     */
    @GetMapping("/get_info")
    public BaseResponse<Student> getStudentInfo(String studentNumber) {
        log.info("获取学生信息,{}", studentNumber);
        //todo: 走Redis
        Object object = redisTemplate.opsForValue().get("student:student_" + studentNumber);
        if (object != null) {
            Student student = (Student) object;
            student.setPassword(null);
            return Result.success(student);
        } else {
            Student student = studentService.getById(studentNumber);
            if (student == null) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
            } else {
                redisTemplate.opsForValue().set("student:student_" + studentNumber, student, 7, TimeUnit.DAYS);
                student.setPassword(null);

                return Result.success(student);
            }
        }
    }

    /**
     * 退出登录
     *
     * @return
     */
    @GetMapping("/logout_student")
    public BaseResponse<String> logoutStudent() {
        log.info("学生退出登录");

        return Result.success("退出成功");
    }

    @GetMapping("/getStatus/{studentNumber}")
    public BaseResponse<StudentTimesVO> selectStudentTimesById(@PathVariable("studentNumber") String studentNumber) {
        log.info("根据studentNumber查询学生信息 ：studentNumber:{}", studentNumber);
        StudentTimesVO studentTimes = studentService.selectStudentTimes(studentNumber);
        return Result.success(studentTimes);
    }

}
